#include "lifeLampsControl.h"


LifeLampsControl::LifeLampsControl()
{

}

LifeLampsControl::~LifeLampsControl(void)
{
    delete strip;
    strip = nullptr;
    if (lifeLampsControlList.size() != 0)
    {
        lifeLampsControlList.clear();//清空容器
    }
    KillThread = true;
}

void LifeLampsControl::init(unsigned char pin_LED_dat, unsigned char pin_LED_clk, unsigned int numLED)
{
    strip = new SK9822(pin_LED_dat, pin_LED_clk, numLED); // 新建ws2812b的控制对象
    strip->clear(); //所有的led灯全部置零
    testDemo();
    ReInit = true;//控制线程需要初始化
    KillThread = false;
    std::thread controlLamps_th(&LifeLampsControl::controlLampsThread, this);
    controlLamps_th.detach();
}

LED_RGB LifeLampsControl::decodeIntToRGB(int dat)
{
    unsigned char R = (0x00FF0000 & dat) >> 16;
    unsigned char G = (0x0000FF00 & dat) >> 8;
    unsigned char B = (0x000000FF & dat);
    return LED_RGB(R,G,B);
}


bool LifeLampsControl::insertData(int n,LifeLampStruct & lls)
{
    auto index = lifeLampsControlList.begin();
    for(;index != lifeLampsControlList.end();index++)
    {
        if (index->n == n-1)
        {
            lifeLampsControlList.insert((++index),lls);
        }
    }
    return true;
}

int RGB2int(LED_RGB & rgb)
{
    return ((rgb.R<<16)|(rgb.G<<8)|(rgb.B));
}

void printLifeLampStruct(LifeLampStruct & lifeLS)
{
    // LOG(INFO) << "n = " << (int)lifeLS.n << ",t = " << (int)lifeLS.time << std::hex << ",L1 = " << RGB2int(lifeLS.lamps[0]) \
    // << ",L2 = "<< RGB2int(lifeLS.lamps[1])  << ",L3 = " << RGB2int(lifeLS.lamps[2])  << ",L4 = " << RGB2int(lifeLS.lamps[3])\
    // << ",L5 = " << RGB2int(lifeLS.lamps[4]);
}


void LifeLampsControl::decodeJsonList(Json::Value lifeLampsList, bool IsLoopEnable)
{
    //先判断线程是否在运行，如果在运行的话，就停止
    ws2812bMutex.lock();
    lifeLampsControlList.clear();//清空List
    size_t ListSize = lifeLampsList.size();
    for(size_t i = 0; i < ListSize; i++){
        Json::Value lamp = lifeLampsList[i];
        LifeLampStruct tempLamps;
        int L1,L2,L3,L4,L5,T,n;
        if (lamp.isMember("L1")){
            L1 = lamp["L1"].asInt();
            tempLamps.lamps[0] = decodeIntToRGB(L1);
        }
        if (lamp.isMember("L2")){
            L2 = lamp["L2"].asInt();
            tempLamps.lamps[1] = decodeIntToRGB(L2);
        }
        if (lamp.isMember("L3")){
            L3 = lamp["L3"].asInt();
            tempLamps.lamps[2] = decodeIntToRGB(L3);
        }
        if (lamp.isMember("L4")){
            L4 = lamp["L4"].asInt();
            tempLamps.lamps[3] = decodeIntToRGB(L4);
        }
        if (lamp.isMember("L5")){
            L5 = lamp["L5"].asInt();
            tempLamps.lamps[4] = decodeIntToRGB(L5);
        }
        if (lamp.isMember("T")){
            T = lamp["T"].asInt();
            tempLamps.time = T;
        }
        if (lamp.isMember("n")){
            n = lamp["n"].asInt();
            tempLamps.n = n;
        }
        if (lifeLampsControlList.empty())
        {
            lifeLampsControlList.push_back(tempLamps);
        }
        else if (lifeLampsControlList.back().n == n - 1){
            lifeLampsControlList.push_back(tempLamps);
        }
        // else if (lifeLampsControlList.back()->n != n - 1) // 稳定安全的接口
        // {
        //      insertData(n,tempLamps);
        // }
        else if (lifeLampsControlList.back().n > n - 1) // 只要大于它就添加
        {
            int next = lifeLampsControlList.rbegin()->n;
            lifeLampsControlList.push_back(tempLamps);
            lifeLampsControlList.rbegin()->n = next + 1;
        }
    }
    LoopEnable_cur = IsLoopEnable;//最后再修改这个
    ReInit = true;
    ws2812bMutex.unlock();
}

void LifeLampsControl::write2sk9822(LifeLampStruct & lampS)
{
    for(int i = 0; i < LED_num; i++)
    {
        strip->setLED(i, lampS.lamps[i].R, lampS.lamps[i].G, lampS.lamps[i].B);
        strip->setLED(LED_num*2 - i -1, lampS.lamps[i].R, lampS.lamps[i].G, lampS.lamps[i].B);
    }
    strip->update();
}


void LifeLampsControl::controlLampsThread(void)
{
    // LOG(INFO) << "controlLampsThread begin !";
    auto index = lifeLampsControlList.begin(); // 初始化列表的初始位置
    volatile int delayTime = 100; 
    while(!KillThread)
    {
        if (ReInit)//需要重新初始化
        {
            ws2812bMutex.lock();
            index = lifeLampsControlList.begin();
            ws2812bMutex.unlock();
            ReInit = false;
        }
        if (lifeLampsControlList.empty())
        {
            delay(100);//等100ms
        }
        else{
            LifeLampStruct tempData;
            if (!LoopEnable_cur)//如果不循环，就删除执行后的数据
            {
                ws2812bMutex.lock();
                tempData = lifeLampsControlList.front();
                lifeLampsControlList.pop_front();//删除最前面那个
                ws2812bMutex.unlock();
            }
            else
            {
                ws2812bMutex.lock();
                tempData = *(index);
                if (++index == lifeLampsControlList.end())
                    index = lifeLampsControlList.begin();
                ws2812bMutex.unlock();
            }
            write2sk9822(tempData);
            delayTime = tempData.time;
            delay(delayTime % 100); //先把100ms以内的延时去掉
            while (delayTime > 100)
            {
                if (ReInit) //如果新的数据到了，就退出，正常执行新的数据
                    break;
                delay(100);
                delayTime -= 100;
            }
        }
    }
    // LOG(INFO) << "controlLampsThread exti !";
}



void LifeLampsControl::testDemo(void)
{
    Json::Value lifeLamps(Json::arrayValue);
    for (int i = 0; i < 17; ++i) {
        Json::Value instruction(Json::objectValue);
        instruction["n"] = i;
        instruction["T"] = (i < 11) ? 250 : 500;
        switch(i)
        {
            case 4:
                instruction["L5"] = 0x00FF00;
            case 3:
                instruction["L4"] = 0x00FF00;
            case 2:
                instruction["L3"] = 0x00FF00;
            case 1:
                instruction["L2"] = 0x00FF00;
            case 0:
                instruction["L1"] = 0x00FF00;
                break;
            case 5:
                instruction["L5"] = 0xFF0000;
                instruction["L4"] = 0x00FF00;
                instruction["L3"] = 0x00FF00;
                instruction["L2"] = 0x00FF00;
                instruction["L1"] = 0x00FF00;
                break;
            case 6:
                instruction["L5"] = 0xFF0000;
                instruction["L4"] = 0xFF0000;
                instruction["L3"] = 0x00FF00;
                instruction["L2"] = 0x00FF00;
                instruction["L1"] = 0x00FF00;
                break;
            case 7:
                instruction["L5"] = 0xFF0000;
                instruction["L4"] = 0xFF0000;
                instruction["L3"] = 0xFF0000;
                instruction["L2"] = 0x00FF00;
                instruction["L1"] = 0x00FF00;
                break;
            case 8:
                instruction["L5"] = 0xFF0000;
                instruction["L4"] = 0xFF0000;
                instruction["L3"] = 0xFF0000;
                instruction["L2"] = 0xFF0000;
                instruction["L1"] = 0x00FF00;
                break;
            case 9:
                instruction["L5"] = 0xFF0000;
                instruction["L4"] = 0xFF0000;
                instruction["L3"] = 0xFF0000;
                instruction["L2"] = 0xFF0000;
                instruction["L1"] = 0xFF0000;
                break;
            case 10:
                instruction["L5"] = 0x000000;
                instruction["L4"] = 0x000000;
                instruction["L3"] = 0x000000;
                instruction["L2"] = 0x000000;
                instruction["L1"] = 0x000000;
                break;
            case 11:
                instruction["L5"] = 0xFF0000;
                instruction["L4"] = 0xFF0000;
                instruction["L3"] = 0xFF0000;
                instruction["L2"] = 0xFF0000;
                instruction["L1"] = 0xFF0000;
                break;
            case 12:
                instruction["L5"] = 0x000000;
                instruction["L4"] = 0x000000;
                instruction["L3"] = 0x000000;
                instruction["L2"] = 0x000000;
                instruction["L1"] = 0x000000;
                break;
            case 13:
                instruction["L5"] = 0xFF0000;
                instruction["L4"] = 0xFF0000;
                instruction["L3"] = 0xFF0000;
                instruction["L2"] = 0xFF0000;
                instruction["L1"] = 0xFF0000;
                break;
            case 14:
                instruction["L5"] = 0x000000;
                instruction["L4"] = 0x000000;
                instruction["L3"] = 0x000000;
                instruction["L2"] = 0x000000;
                instruction["L1"] = 0x000000;
                break;
            case 15:
                instruction["L5"] = 0xFF0000;
                instruction["L4"] = 0xFF0000;
                instruction["L3"] = 0xFF0000;
                instruction["L2"] = 0xFF0000;
                instruction["L1"] = 0xFF0000;
                break;
            case 16:
                instruction["L5"] = 0x000000;
                instruction["L4"] = 0x000000;
                instruction["L3"] = 0x000000;
                instruction["L2"] = 0x000000;
                instruction["L1"] = 0x000000;
                break;
        } 
        lifeLamps.append(instruction);
    }
    decodeJsonList(lifeLamps, false);
}